package BundleAnalysis;

import java.util.Comparator;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;

import sun.text.CompactShortArray.Iterator;


public class BundleAnalyzerImpl implements BundleAnalyzer {

	private ServiceReference 	_svcRef			=	null;
	private BundleContext		_bundleContext	=	null;
	private	Bundle[]			_bundles		=	null;
	
    static public Set getPackageClosure(PackageAdmin pkgAdmin,
    									Bundle[]     allBundles,
    									Bundle       target,
    									Set          handled) {
    	if ( pkgAdmin == null ) return null;
    	
    	if ( handled == null )
    		handled = new HashSet();
    	
    	Set closure	=	new TreeSet( bundleIdComparator );
    	
    	for( int i = 0;  i < allBundles.length ; i++) {
    		ExportedPackage[] pkgs	=	pkgAdmin.getExportedPackages( allBundles[i] );
    		
    		for( int j = 0 ; pkgs != null && j < pkgs.length ; j++ ) {
    			Bundle[] blz	=	pkgs[j].getImportingBundles();
    			
    			for( int k = 0 ; blz != null && k < blz.length ; k++ ){
    				if( blz[k].getBundleId() == target.getBundleId() ) {
    					closure.add( allBundles[i] );
    					
    					if( handled.contains( allBundles[i] )) {
    						handled.add( allBundles[i] );
    						
    						Set trans = getPackageClosure( pkgAdmin, allBundles, allBundles[i], handled );
    						closure.addAll(trans);
    					}
    				}
    			}
    		}
    	}	
    	return closure;
    }

	public static Comparator bundleIdComparator = new BundleIdComparator();

	public static class BundleIdComparator implements Comparator {
		public int compare(Object o1, Object o2) {
			Bundle b1 = (Bundle)o1;
			Bundle b2 = (Bundle)o2;

			return (int)(b1.getBundleId() - b2.getBundleId());
	    }

	    public boolean equals(Object obj) {
	    	return obj.getClass().equals(BundleIdComparator.class);
	    }
	}
	
	public BundleAnalyzerImpl(BundleContext bc)
	{
		_bundleContext	=	bc;
	}
	
	public String[] Analyze(Bundle[] bundles) {
	
		_svcRef	=	_bundleContext.getServiceReference(PackageAdmin.class.getName() );
		PackageAdmin pkgAdmin =  (PackageAdmin) _bundleContext.getService(_svcRef);
		
		if ( pkgAdmin == null ) return null;
		
		Bundle[] bl = getBundleArray();
		Set pkgClosure	=	new TreeSet(bundleIdComparator);
		
		for( int i = 0; i < bundles.length ; i++)
		{
			Set ret = getPackageClosure( pkgAdmin, bl, bundles[i], null);
			pkgClosure.addAll( ret );
		}
		
		if( pkgClosure.size() != 0 )
		{
			for( java.util.Iterator itr = pkgClosure.iterator() ; itr.hasNext(); ) {
				Bundle depBundle = (Bundle) itr.next();
			//	String s = (String) depBundle.getHeaders("Bundle-Name");
				Dictionary d = depBundle.getHeaders();
				String s = d.get("Bundle-Name").toString();
			
				
				System.out.println( s ); 
			}
		}
		//System.out.println( pkgClosure.toString() );

		return null;
	}

	protected Bundle[] getAndSortBundles() {
	    Bundle[] bl = _bundleContext.getBundles();
	    SortedSet set = new TreeSet(bundleIdComparator);
	    for(int i = 0; i < bl.length; i++) {
	      set.add(bl[i]);
	    }

	    set.toArray(bl);    

	    return bl;
	  }
	
	protected Bundle[] getBundleArray() {

	    if(_bundles == null) {
	    	_bundles = getAndSortBundles();
	    }

	    return _bundles;
	  }
}
